<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>语音对话测试</title>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            color: white;
        }
        
        .container {
            background: rgba(255, 255, 255, 0.1);
            backdrop-filter: blur(10px);
            border-radius: 20px;
            padding: 30px;
            box-shadow: 0 8px 32px rgba(31, 38, 135, 0.37);
            border: 1px solid rgba(255, 255, 255, 0.18);
        }
        
        h1 {
            text-align: center;
            margin-bottom: 30px;
            font-size: 2.5em;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
        }
        
        .record-section {
            text-align: center;
            margin: 40px 0;
        }
        
        .record-btn {
            width: 150px;
            height: 150px;
            border-radius: 50%;
            border: none;
            background: linear-gradient(45deg, #ff6b6b, #ee5a24);
            color: white;
            font-size: 18px;
            font-weight: bold;
            cursor: pointer;
            transition: all 0.3s ease;
            box-shadow: 0 8px 25px rgba(255, 107, 107, 0.4);
            user-select: none;
        }
        
        .record-btn:hover {
            transform: scale(1.05);
            box-shadow: 0 12px 35px rgba(255, 107, 107, 0.6);
        }
        
        .record-btn:active {
            transform: scale(0.95);
        }
        
        .record-btn.recording {
            background: linear-gradient(45deg, #ff4757, #c44569);
            animation: pulse 1.5s infinite;
        }
        
        @keyframes pulse {
            0% { box-shadow: 0 0 0 0 rgba(255, 71, 87, 0.7); }
            70% { box-shadow: 0 0 0 20px rgba(255, 71, 87, 0); }
            100% { box-shadow: 0 0 0 0 rgba(255, 71, 87, 0); }
        }
        
        .status {
            margin: 20px 0;
            padding: 15px;
            border-radius: 10px;
            background: rgba(255, 255, 255, 0.1);
            text-align: center;
            font-size: 16px;
            min-height: 20px;
        }
        
        .status.recording {
            background: rgba(255, 71, 87, 0.2);
            border: 1px solid rgba(255, 71, 87, 0.5);
        }
        
        .status.processing {
            background: rgba(255, 193, 7, 0.2);
            border: 1px solid rgba(255, 193, 7, 0.5);
        }
        
        .status.success {
            background: rgba(40, 167, 69, 0.2);
            border: 1px solid rgba(40, 167, 69, 0.5);
        }
        
        .status.error {
            background: rgba(220, 53, 69, 0.2);
            border: 1px solid rgba(220, 53, 69, 0.5);
        }
        
        .audio-player {
            margin: 20px 0;
            text-align: center;
        }
        
        audio {
            width: 100%;
            max-width: 400px;
            margin: 10px 0;
        }
        
        .instructions {
            background: rgba(255, 255, 255, 0.1);
            border-radius: 10px;
            padding: 20px;
            margin: 20px 0;
        }
        
        .instructions h3 {
            margin-top: 0;
            color: #ffd700;
        }
        
        .instructions ul {
            text-align: left;
            padding-left: 20px;
        }
        
        .instructions li {
            margin: 8px 0;
        }
        
        .loading {
            display: inline-block;
            width: 20px;
            height: 20px;
            border: 3px solid rgba(255,255,255,.3);
            border-radius: 50%;
            border-top-color: #fff;
            animation: spin 1s ease-in-out infinite;
        }
        
        @keyframes spin {
            to { transform: rotate(360deg); }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>🎤 语音对话测试</h1>
        
        <div class="instructions">
            <h3>📋 使用说明</h3>
            <ul>
                <li>按住红色按钮开始录音</li>
                <li>松开按钮结束录音并自动上传</li>
                <li>系统会自动识别语音并生成回复</li>
                <li>回复的音频会自动播放</li>
            </ul>
        </div>
        
        <div class="record-section">
            <button id="recordBtn" class="record-btn">
                按住录音
            </button>
        </div>
        
        <div id="status" class="status">
            准备就绪，请按住按钮开始录音
        </div>
        
        <div class="audio-player">
            <div id="recordedAudio"></div>
            <div id="responseAudio"></div>
        </div>
    </div>

    <script>
        let mediaRecorder;
        let audioChunks = [];
        let isRecording = false;
        
        const recordBtn = document.getElementById('recordBtn');
        const status = document.getElementById('status');
        const recordedAudio = document.getElementById('recordedAudio');
        const responseAudio = document.getElementById('responseAudio');
        
        // 更新状态显示
        function updateStatus(message, type = '') {
            status.textContent = message;
            status.className = 'status ' + type;
        }
        
        // 初始化录音功能
        async function initRecording() {
            try {
                const stream = await navigator.mediaDevices.getUserMedia({ 
                    audio: {
                        echoCancellation: true,
                        noiseSuppression: true,
                        sampleRate: 44100
                    } 
                });
                
                mediaRecorder = new MediaRecorder(stream, {
                    mimeType: 'audio/webm;codecs=opus'
                });
                
                mediaRecorder.ondataavailable = (event) => {
                    if (event.data.size > 0) {
                        audioChunks.push(event.data);
                    }
                };
                
                mediaRecorder.onstop = async () => {
                    const audioBlob = new Blob(audioChunks, { type: 'audio/webm' });
                    audioChunks = [];
                    
                    // 显示录制的音频
                    const audioUrl = URL.createObjectURL(audioBlob);
                    recordedAudio.innerHTML = `
                        <p>📼 录制的音频：</p>
                        <audio controls>
                            <source src="${audioUrl}" type="audio/webm">
                        </audio>
                    `;
                    
                    // 上传音频
                    await uploadAudio(audioBlob);
                };
                
                updateStatus('✅ 录音功能已就绪，按住按钮开始录音', 'success');
                
            } catch (error) {
                console.error('获取麦克风权限失败:', error);
                updateStatus('❌ 无法获取麦克风权限，请检查浏览器设置', 'error');
            }
        }
        
        // 开始录音
        function startRecording() {
            if (!mediaRecorder || isRecording) return;
            
            isRecording = true;
            audioChunks = [];
            recordBtn.classList.add('recording');
            recordBtn.textContent = '🔴 录音中...';
            updateStatus('🎙️ 正在录音中，松开按钮结束录音', 'recording');
            
            mediaRecorder.start();
        }
        
        // 停止录音
        function stopRecording() {
            if (!mediaRecorder || !isRecording) return;
            
            isRecording = false;
            recordBtn.classList.remove('recording');
            recordBtn.textContent = '按住录音';
            updateStatus('⏹️ 录音结束，正在处理...', 'processing');
            
            mediaRecorder.stop();
        }
        
        // 上传音频到后端
        async function uploadAudio(audioBlob) {
            try {
                updateStatus('📤 正在上传音频并处理... <span class="loading"></span>', 'processing');
                
                // 将webm转换为wav格式（如果需要的话）
                const formData = new FormData();
                formData.append('audio', audioBlob, 'recording.webm');
                
                const response = await fetch('/talk/demo', {
                    method: 'POST',
                    body: formData
                });
                
                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }
                
                const result = await response.json();
                
                if (result.success) {
                    updateStatus('✅ 处理成功，正在播放回复音频', 'success');
                    
                    // 播放回复音频
                    const responseUrl = result.data;
                    responseAudio.innerHTML = `
                        <p>🔊 AI回复音频：</p>
                        <audio controls autoplay>
                            <source src="${responseUrl}" type="audio/mpeg">
                        </audio>
                    `;
                    
                    setTimeout(() => {
                        updateStatus('准备就绪，请按住按钮开始录音', '');
                    }, 3000);
                    
                } else {
                    throw new Error(result.message || '处理失败');
                }
                
            } catch (error) {
                console.error('上传失败:', error);
                updateStatus(`❌ 上传失败: ${error.message}`, 'error');
                
                setTimeout(() => {
                    updateStatus('准备就绪，请按住按钮开始录音', '');
                }, 3000);
            }
        }
        
        // 事件监听器
        recordBtn.addEventListener('mousedown', startRecording);
        recordBtn.addEventListener('mouseup', stopRecording);
        recordBtn.addEventListener('mouseleave', stopRecording);
        
        // 触摸设备支持
        recordBtn.addEventListener('touchstart', (e) => {
            e.preventDefault();
            startRecording();
        });
        
        recordBtn.addEventListener('touchend', (e) => {
            e.preventDefault();
            stopRecording();
        });
        
        // 防止右键菜单
        recordBtn.addEventListener('contextmenu', (e) => {
            e.preventDefault();
        });
        
        // 页面加载完成后初始化
        window.addEventListener('load', initRecording);
        
        // 页面卸载时清理资源
        window.addEventListener('beforeunload', () => {
            if (mediaRecorder && mediaRecorder.stream) {
                mediaRecorder.stream.getTracks().forEach(track => track.stop());
            }
        });
    </script>
</body>
</html>